#include <head.h>
#include "share.h"

int TCP_server_sockfd_init(const char *argv1, const char *argv2, struct sockaddr_in *serveraddr)
{
	int ret;
	int sockfd;

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sockfd < 0){
		err_log("fail to socket\n");
	}

	memset(serveraddr, 0, sizeof(struct sockaddr_in));
	
	serveraddr->sin_family = AF_INET;
	serveraddr->sin_addr.s_addr = inet_addr(argv1);
	serveraddr->sin_port = htons(atoi(argv2));

	ret = bind(sockfd, (struct sockaddr *)serveraddr, sizeof(struct sockaddr_in));
	if(ret < 0){
		err_log("fail to bind\n");
	}

	ret = listen(sockfd, 10);
	if(ret < 0){
		err_log("fail to listen\n");
	}

	return sockfd;
}

int TCP_client_sockfd_init(const char *argv1, const char *argv2, struct sockaddr_in *serveraddr)
{
	int ret;
	int sockfd;

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sockfd < 0){
		err_log("fail to socket\n");
	}

	memset(serveraddr, 0, sizeof(struct sockaddr_in));
	
	serveraddr->sin_family = AF_INET;
	serveraddr->sin_addr.s_addr = inet_addr(argv1);
	serveraddr->sin_port = htons(atoi(argv2));

	return sockfd;
}

int TCP_REUSEADDR_sockfd_init(const char *argv1, const char *argv2, struct sockaddr_in *serveraddr)//地址重复绑定
{
	int ret;
	int optval = 1;
	int sockfd;

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sockfd < 0){
		err_log("fail to socket\n");
	}

	ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(int));
	if(ret < 0){
		err_log("fail to setsockopt\n");
	}

	memset(serveraddr, 0, sizeof(struct sockaddr_in));
	
	serveraddr->sin_family = AF_INET;
	serveraddr->sin_addr.s_addr = inet_addr(argv1);
	serveraddr->sin_port = htons(atoi(argv2));

	ret = bind(sockfd, (struct sockaddr *)serveraddr, sizeof(struct sockaddr_in));
	if(ret < 0){
		err_log("fail to bind\n");
	}

	ret = listen(sockfd, 10);
	if(ret < 0){
		err_log("fail to listen\n");
	}

	return sockfd;
}

int UDP_server_sockfd_init(const char *argv1, const char *argv2, struct sockaddr_in *serveraddr)
{
	int ret;
	int sockfd;

	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if(sockfd < 0){
		err_log("fail to socket\n");
	}

	memset(serveraddr, 0, sizeof(struct sockaddr_in));

	serveraddr->sin_family = AF_INET;
	serveraddr->sin_addr.s_addr = inet_addr(argv1);
	serveraddr->sin_port = htons(atoi(argv2));

	ret = bind(sockfd, (struct sockaddr *)serveraddr, sizeof(struct sockaddr_in));
	if(ret < 0){
		err_log("fail to bind\n");
	}

	return sockfd;
}

int UDP_client_sockfd_init(const char *argv1, const char *argv2, struct sockaddr_in *clientaddr)
{
	int ret;
	int sockfd;

	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if(sockfd < 0){
		err_log("fail to socket\n");
	}

	memset(clientaddr, 0, sizeof(struct sockaddr_in));

	clientaddr->sin_family = AF_INET;
	clientaddr->sin_addr.s_addr = inet_addr(argv1);
	clientaddr->sin_port = htons(atoi(argv2));

	return sockfd;
}

int UDP_broadcast_snd_sockfd_init(const char *argv1, const char *argv2, struct sockaddr_in *broadcastaddr)//广播
{
	int ret;
	int optval = 1;
	int sockfd;

	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if(sockfd < 0){
		err_log("fail to socket\n");
	}

	ret = setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &optval, sizeof(int));
	if(ret < 0){
		err_log("fail to setsockopt\n");
	}

	memset(broadcastaddr, 0, sizeof(struct sockaddr_in));

	broadcastaddr->sin_family = AF_INET;
	broadcastaddr->sin_addr.s_addr = inet_addr(argv1);
	broadcastaddr->sin_port = htons(atoi(argv2));

	ret = bind(sockfd, (struct sockaddr *)broadcastaddr, sizeof(struct sockaddr_in));
	if(ret < 0){
		err_log("fail to bind\n");
	}

	return sockfd;
}

int UDP_multicast_recv_sockfd_init(const char *argv1, const char *argv2, struct sockaddr_in *multiaddr)
{
	int ret;
	int optval = 1;
	int sockfd;
	struct ip_mreq mreq;

	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if(sockfd < 0){
		err_log("fail to socket\n");
	}

	memset(multiaddr, 0, sizeof(struct sockaddr_in));

	multiaddr->sin_family = AF_INET;
	multiaddr->sin_addr.s_addr = inet_addr(argv1);
	multiaddr->sin_port = htons(atoi(argv2));

	ret = bind(sockfd, (struct sockaddr *)multiaddr, sizeof(struct sockaddr_in));
	if(ret < 0){
		err_log("fail to bind\n");
	}

	mreq.imr_multiaddr.s_addr = inet_addr(argv1);
	mreq.imr_interface.s_addr = htonl(INADDR_ANY);

	ret = setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
	if(ret < 0){
		err_log("fail to setsockopt\n");
	}

	return sockfd;
}

int TCP_server_local_sock_init(const char *argv1, struct sockaddr_un *serveraddr)
{
	int ret;
	int sockfd;

	sockfd = socket(PF_UNIX, SOCK_STREAM, 0);
	if(sockfd < 0){
		err_log("fail to socket\n");
	}

	memset(serveraddr, 0, sizeof(struct sockaddr_un));

	serveraddr->sun_family = PF_UNIX;
	strcpy(serveraddr->sun_path, argv1);

	ret = bind(sockfd, (struct sockaddr *)serveraddr, sizeof(struct sockaddr));
	if(ret < 0){
		err_log("fail to bind\n");
	}

	ret = listen(sockfd, 10);
	if(ret < 0){
		err_log("fail to listen\n");
	}

	return sockfd;
}

int TCP_client_local_sock_init(const char *argv1, struct sockaddr_un *serveraddr)
{
	int ret;
	int sockfd;

	sockfd = socket(PF_UNIX, SOCK_STREAM, 0);
	if(sockfd < 0){
		err_log("fail to socket\n");
	}

	memset(serveraddr, 0, sizeof(struct sockaddr_un));

	serveraddr->sun_family = PF_UNIX;
	strcpy(serveraddr->sun_path, argv1);

	return sockfd;
}

int UDP_sever_local_sockfd_init(const char *argv1, struct sockaddr_un *serveraddr)
{
	int ret;
	int sockfd;

	sockfd = socket(PF_UNIX, SOCK_DGRAM, 0);
	if(sockfd < 0){
		err_log("fail to socket\n");
	}

	memset(serveraddr, 0, sizeof(struct sockaddr_un));

	serveraddr->sun_family = PF_UNIX;
	strcpy(serveraddr->sun_path, argv1);

	ret = bind(sockfd, (struct sockaddr *)serveraddr, sizeof(struct sockaddr));
	if(ret < 0){
		if(errno == 98){
			printf("errno:%d\n",errno);
		}else{
			err_log("fail to bind\n");
		}
	}

	return sockfd;
}

int UDP_client_local_sockfd_init(const char *argv1, const char *argv2, struct sockaddr_un *serveraddr)
{
	int ret;
	int sockfd;
	struct sockaddr_un clientaddr;

	sockfd = socket(PF_UNIX, SOCK_DGRAM, 0);
	if(sockfd < 0){
		err_log("fail to socket\n");
	}

	memset(serveraddr, 0, sizeof(struct sockaddr_un));

	serveraddr->sun_family = PF_UNIX;
	strcpy(serveraddr->sun_path, argv1);

	clientaddr.sun_family = PF_UNIX;
	strcpy(clientaddr.sun_path, argv2);

	ret = bind(sockfd, (struct sockaddr *)&clientaddr, sizeof(struct sockaddr));
	if(ret < 0){
		if(errno == 98){
			printf("errno:%d\n",errno);
		}else{
			err_log("fail to bind\n");
		}
	}

	return sockfd;
}

